﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

using Qiang.Controls;
using Qiang.Topology.Geometries;
using Qiang.Data;

using Point = System.Drawing.Point;

namespace GisMap
{
    public class MapFunctionAddSegment : MapFunction
    {
        public MapFunctionAddSegment()
            : base()
        {
            Cursor = System.Windows.Forms.Cursors.Cross;
        }


        private MapVectorLayer _shpLayer;

        public MapVectorLayer ShpLayer
        {
            get { return _shpLayer; }
            set { _shpLayer = value; }
        }

        private bool _drawing = false;
        private INodeShape startNode = null;
        private List<IVertexShape> _lstPoint;
        private INodeShape endNode = null; 

        private Point _mousePos;


        public override void Active()
        {
            if (_shpLayer == null || _shpLayer.Dataset == null) return;
            base.Active();
            this._lstPoint = new List<IVertexShape>();           
        }


        public override void Deactive()
        {
            base.Deactive();
        }


        protected override  void  OnPaint(MapPaintArgs args)
        {
            if (this._drawing == false) return;

            List<Point> lstPoint = new List<Point>();

            if (this.startNode != null)
            {
                Point startPt = this.MapControl.ProjToPixel(this.startNode.Point);
                args.MapGraphics.FillEllipse(Brushes.Black, new Rectangle(startPt.X - 3, startPt.Y - 3, 6, 6));
            }

          
           
            if (this._lstPoint.Count > 0)
            {
                Point startPt = this.MapControl.ProjToPixel(this.startNode.Point);
                args.MapGraphics.DrawLine(new Pen(Color.Black), startPt, this.MapControl.ProjToPixel(this._lstPoint[0].Point));
                args.MapGraphics.DrawLine(new Pen(Color.Red), this.MapControl.ProjToPixel(this._lstPoint[this._lstPoint.Count - 1].Point), this._mousePos);
            }
            else if (this .startNode!=null )
            {
                args.MapGraphics.DrawLine(new Pen(Color.Red), this.MapControl.ProjToPixel(this.startNode.Point), this._mousePos);
            }

            if (this._lstPoint.Count > 1)
            {
                //Point startPt = this.MapControl.ProjToPixel(this.startNode.Point);
                //lstPoint.Add(startPt);

                for (int i = 0; i < this._lstPoint.Count; i++)
                {
                    Point pt = this.MapControl.ProjToPixel(this._lstPoint[i].Point);
                    lstPoint.Add(pt);
                    args.MapGraphics.FillEllipse(Brushes.Black, new Rectangle(pt.X - 3, pt.Y - 3, 6, 6));
                }
                args.MapGraphics.DrawLines(new Pen(Color.Black), lstPoint.ToArray());
            }

            base.OnPaint(args);
        }


        protected override void OnMouseDown(MapMouseArgs e)
        {
            if (e.Button != System.Windows.Forms.MouseButtons.Left) return;
            if (this._drawing == false)
            {
                this._drawing = true;                
            }

            base.OnMouseDown(e);
        }


        protected override void OnMouseUp(MapMouseArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if (this._lstPoint == null) this._lstPoint = new List<IVertexShape>();

                //这里还要加上拓扑的关系，判断图层是否已包含当前点
                INodeShape node = this._shpLayer.TopologyPoint(this.MapControl, e.Location);

                 if (node == null)
                 {
                     Coordinate pt = e.Control.PixelToProj(e.Location);
                     if (this.startNode == null)
                     {
                         this.startNode = new NodeShape(pt);
                     }
                     else
                     {
                         bool b = this.TopologyStartPoint(e.Location);

                         if (b == true) //如果和起始节点重合
                         {
                             if (this._lstPoint.Count > 0)
                             {
                                 this.endNode = startNode;
                                 this.FinishLine();
                             }
                             else
                             {
                                 
                             }
                         }
                         else
                         {
                             VertexShape vertexPt = new VertexShape(pt);

                             this._lstPoint.Add(vertexPt);

                             Point pt1 = this.MapControl.ProjToPixel(this._lstPoint[this._lstPoint.Count - 1].Point);
                             Point pt2;

                             if (this._lstPoint.Count > 1)
                             {
                                 pt2 = this.MapControl.ProjToPixel(this._lstPoint[this._lstPoint.Count - 2].Point);
                             }
                             else
                             {
                                 pt2 = this.MapControl.ProjToPixel(this.startNode.Point);
                             }

                             Rectangle invalid = new Rectangle(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y), Math.Abs(pt1.X - pt2.X), Math.Abs(pt1.Y - pt2.Y));
                             invalid.Inflate(20, 20);
                             this.MapControl.Invalidate(invalid);
                         }
                                                 
                     }
                 }
                 else
                 {
                     if (this.startNode == null)
                     {
                         this.startNode = node;
                     }
                     else
                     {
                         this.endNode = node;
                         this.FinishLine();
                     }
 
                 }

            }
            else if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                this._drawing = false;
                if (this.endNode == null)
                {
                    if (this._lstPoint.Count > 0)
                    {
                        this.endNode = new NodeShape(this._lstPoint[this._lstPoint.Count - 1].Point);
                        this._lstPoint.RemoveAt(this._lstPoint.Count - 1);
                    }
                    else
                    {
                        this.startNode = null;
                        this.MapControl.Invalidate();
                    }
                }
                this.FinishLine();                
            }


            base.OnMouseUp(e);
        }

        protected override void OnMouseMove(MapMouseArgs e)
        {
            if (this._drawing == false) return;

            if (this._lstPoint.Count > 0 || this.startNode!=null)
            {
                Point pt;

                if (this._lstPoint.Count > 0)
                {
                    pt = e.Control.ProjToPixel(this._lstPoint[this._lstPoint.Count - 1].Point);
                }
                else
                {
                    pt = e.Control.ProjToPixel(this.startNode.Point);
                }
                
                Rectangle oldRect = new Rectangle(Math.Min(pt.X, this._mousePos.X), Math.Min(pt.Y, this._mousePos.Y), Math.Abs(pt.X - this._mousePos.X), Math.Abs(pt.Y - this._mousePos.Y));
                Rectangle newRect = new Rectangle(Math.Min(e.Location.X, pt.X), Math.Min(e.Location.Y, pt.Y), Math.Abs(e.Location.X - pt.X), Math.Abs(e.Location.Y - pt.Y));

                Rectangle invalidate = Rectangle.Union(oldRect, newRect);
                invalidate.Inflate(20, 20);

                this.MapControl.Invalidate(invalidate);
            }

            this._mousePos = e.Location;

            base.OnMouseMove(e);
        }


        private bool TopologyStartPoint(Point pt)
        {
            Rectangle rect = new Rectangle(pt.X - 3, pt.Y - 3, 6, 6);

            Point startPt = this.MapControl.ProjToPixel(this.startNode.Point);

            if (rect.Contains(startPt))
            {
                return true;
            }
            return false;
        }

        private void FinishLine()
        {
            if (this.startNode == null) return;
            if (this.endNode == null) return;

            if (this._shpLayer == null || this._shpLayer.Dataset == null)
            {
                this._lstPoint = new List<IVertexShape>();
                return;
            }

            ISegmentShape segment = new SegmentShape(this.startNode, this.endNode, this._lstPoint);
            _shpLayer.Dataset.AddShape(segment);
            this._lstPoint = new List<IVertexShape>();
            this.startNode = null;
            this.endNode = null; 
        }


    }
}
